﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<string>
#include<list>
#include<assert.h>
using namespace std;


////由于引用折叠限定，f1实例化以后总是一个左值引用
//template<class T>
//void f1(T& x)
//{}
//
////由于引用折叠限定，f2实例化后可以是左值引用，也可以是右值引用
//template<class T>
//void f2(T&& x)
//{}
//
//int main()
//{
//	typedef int& lref;
//	typedef int&& rref;
//
//	int n = 0;
//	//引用折叠
//	lref& r1 = n;//r1的类型是 int&
//	lref&& r2 = n;//r2的类型是 int&
//	rref& r3 = n;//r3的类型是 int&
//	rref&& r4 = 1;//r4的类型是 int&&
//
//    //注:n是左值；0是右值，只能被const左值引用或者右值引用。
//	//没有折叠->实例化为void f1(int& x)
//	f1<int>(n);
//	//f1<int>(0);//err 
//
//	//折叠->实例化为void f1(int& x)
//	f1<int&>(n);
//	//f1<int&>(0);//err
//
//	//折叠->实例化为void f1(int& x)
//	f1<int&&>(n);
//	//f1<int&&>(0);//err
//
//	//折叠->实例化为void f1(const int& x)
//	f1<const int&>(n);
//	f1<const int&>(0);
//
//	//折叠->实例化为void f1(const int& x)
//	f1<const int&&>(n);
//	f1<const int&&>(0);
//
//
//
//	//没有折叠->实例化为void f2(int&& x)
//	//f2<int>(n);//err
//	f2<int>(0);
//
//	//折叠->实例化为void f2(int& x)
//	f2<int&>(n);
//	//f2<int&>(0);//err
//
//	//折叠->实例化为void f2(int&& x)
//	//f2<int&&>(n);//err
//	f2<int&&>(0);
//
//	return 0;
//}

//template<class T>
//void Function(T&& t)
//{
//	int a = 0;
//	T x = a;
//	//x++;
//
//	cout << &a << endl;
//	cout << &x << endl << endl;
//}
//
//int main()
//{
//	//10是右值，推导出T为int，模版实例化为void Function(int&& t)
//	Function(10);
//
//	//b是左值，推导出T为int&，引用折叠，模版实例化为void Function(int& t)
//	int b = 1;
//	Function(b);
//
//	//move(b)是右值，推导出T为int，模版实例化为void Function(int&& t)
//	Function(move(b));
//
//	//c是左值，推导出T为const int&，引用折叠，模版实例化为void Function(const int& t)
//	//x不能++,导致Funcion内部会编译报错
//	const int c = 8;// const 左值
//	Function(c);
//
//	//move(c)是右值，推导出T为const int，模版实例化为void Function(const int&& t)
//	//x不能++，导致Funcion内部会编译报错
//	Function(move(c));// const 右值
//
//	return 0;
//}

//template <class T> T&& forward(typename remove_reference<T>::type& arg);
//template <class T> T&& forward(typename remove_reference<T>::type&& arg);

//void Fun(int& x) { cout << "左值引用" << endl; }
//void Fun(const int& x) { cout << "const 左值引用" << endl; }
//void Fun(int&& x) { cout << "右值引用" << endl; }
//void Fun(const int&& x) { cout << "const 右值引用" << endl; }
//
//template<class T>
//void Function(T&& t)
//{
//	Fun(forward<T>(t));
//}
//
//int main()
//{
//	Function(10);//右值
//
//	int a;
//	Function(a);//左值
//
//	Function(move(a));//右值
//
//	const int b = 1;
//	Function(b);//const 左值
//
//	Function(move(b));//const 右值
//
//	return 0;
//}


namespace zsy
{
	class string
	{
	public:
		typedef char* iterator;
		typedef const char* const_iterator;

		iterator begin()
		{
			return _str;
		}

		iterator end()
		{
			return _str + _size;
		}

		const_iterator begin() const
		{
			return _str;
		}

		const_iterator end() const
		{
			return _str + _size;
		}

		string(const char* str = "")
			:_size(strlen(str))
			, _capacity(_size)
		{
			cout << "string(char* str)-构造" << endl;
			_str = new char[_capacity + 1];
			strcpy(_str, str);
		}

		void swap(string& s)
		{
			std::swap(_str, s._str);
			std::swap(_size, s._size);
			std::swap(_capacity, s._capacity);
		}

		//拷贝构造
		string(const string& s)
			:_str(nullptr)
		{
			cout << "string(const string& s)-拷贝构造" << endl;
			reserve(s._capacity);
			for (auto ch : s)
			{
				push_back(ch);
			}
		}

		//移动构造
		string(string&& s)
		{
			cout << "string(string&& s)-移动构造" << endl;
			//转移掠夺你的资源
			swap(s);
		}

		//拷贝赋值
		string& operator=(const string& s)
		{
			cout << "string& operator=(const string& s)-赋值" << endl;
			if (this != &s)
			{
				_str[0] = '\0';
				_size = 0;
				reserve(s._capacity);
				for (auto ch : s)
				{
					push_back(ch);
				}
			}

			return *this;
		}

		//移动赋值
		string& operator=(string&& s)
		{
			cout << "string& operator=(string&& s)-移动赋值" << endl;
			swap(s);

			return *this;
		}

		~string()
		{
			delete[] _str;
			_str = nullptr;
		}

		char& operator[](size_t pos)
		{
			assert(pos < _size);
			return _str[pos];
		}

		void reserve(size_t n)
		{
			if (n > _capacity)
			{
				char* tmp = new(char[n + 1]);
				if (_str)
				{
					strcpy(tmp, _str);
					delete[] _str;
				}

				_str = tmp;
				_capacity = n;
			}
		}

		void push_back(char ch)
		{
			//扩容
			if (_size >= _capacity)
			{
				size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
				reserve(newcapacity);
			}

			_str[_size] = ch;
			++_size;
			_str[_size] = '\0';
		}

		string& operator+=(char ch)
		{
			push_back(ch);

			return *this;
		}

		const char* c_str() const
		{
			return _str;
		}

		size_t size() const
		{
			return _size;
		}

	private:
		char* _str = nullptr;
		size_t _size = 0;
		size_t _capacity = 0;
	};
}

//#include"List.h"
//
//int main()
//{
//	zsy::list<zsy::string> lt;
//	zsy::string s1("11111");
//	lt.push_back(s1);
//	cout << endl;
//
//	zsy::string s2("22222");
//	lt.push_back(move(s2));
//	cout << endl;
//
//	lt.push_back("33333");
//
//	return 0;
//}


//template<class...Args>
//void Print(Args&&... args)
//{
//	//不支持[]访问
//	for (size_t i = 0; i < sizeof...(args); ++i)
//	{
//		cout << args[i] << " ";
//	}
//	cout << endl;
//}


//template<class ...Args>
//void Print(Args... args)
//{
//	for (auto&& e : args...)
//	{
//		cout << e << " ";
//	}
//	cout << endl;
//}


//void ShowList()
//{
//	cout << endl;
//}
//
//template<class T,class ...Args>
//void ShowList(T&& x, Args&&... args)
//{
//	cout << x << " ";
//	ShowList(args...);
//}
//
////编译时递归推导解析参数
//template<class ...Args>
//void Print(Args&&... args)
//{
//	//args是N个参数的参数包
//	//调用ShowList，参数包的第一个传给x
//	//剩下N-1传给第二个参数包
//	ShowList(args...);
//}
//
//int main()
//{
//	Print(1, string("xxxxx"), 2.2);
//
//	return 0;
//}
//
//void ShowList(double x)
//{
//	cout << x << " ";
//	ShowList();
//}
//
//void 


////包扩展
//template<class T>
//int GetArg(const T& x)
//{
//	cout << x << " ";
//
//	return 0;
//}
//
//template<class ...Args>
//void Arguments(Args... args)
//{}
//
//template<class ...Args>
//void Print(Args... args)
//{
//	Arguments(GetArg(args)...);
//	cout << endl;
//}
//
//
//int main()
//{
//	double x = 2.2;
//	Print();//包里有0个参数
//	Print(1);//包里有1个参数
//	Print(1, string("xxxxx"));//包里有2个参数
//	Print(1.1, string("xxxxx"), x);//包里有3个参数
//
//	return 0;
//}



//template<class ...Args>
//void Print(Args&&... args)
//{
//	cout << sizeof...(args) << endl;
//}
//
//int main()
//{
//	double x = 2.2;
//	Print();//包里有0个参数
//	Print(1);//包里有1个参数
//	Print(1, string("xxxxx"));//包里有2个参数
//	Print(1, string("xxxxx"), x);//包里有3个参数
//
//	return 0;
//}
//
////原理一: 编译本质这里会结合引用折叠规则实例化出以下四个函数
//void Print();
//void Print(int&& arg1);
//void Print(int&& arg1, string&& arg2);
//void Print(double&& arg1, string&& arg2, double& arg3);
//
////原理二: 更本质是因为可变参数模版，生成了不同参数个数的函数模版
//void Print();
//
//template<class T1>
//void Print(T1&& arg1);//万能引用
//
//template<class T1, class T2>
//void Print(T1&& arg1, T2&& arg2);
//
//template<class T1, class T2, class T3>
//void Print(T1&& arg1, T2&& arg2, T3&& arg3);




////0-N个参数
//template<class ...Args>
//void Print(Args&&... args)
//{
//	cout << sizeof...(args) << endl;
//}
//
//int main()
//{
//	double x = 2.2;
//	Print();                     //包里有0个参数
//	Print(1);                    //包里有1个参数
//	Print(1, string("xxxxx"));   //包里有2个参数
//	Print(1, string("xxxxx"), x);//包里有3个参数
//
//	return 0;
//}
//
//
//void Print()
//{
//	//...
//};
//
//template<class T1>
//void Print(T1&& arg1)
//{
//	//...
//}
//
//template<class T1, class T2>
//void Print(T1&& arg1, T2&& arg2)
//{
//	//...
//}
//
//template<class T1, class T2, class T3>
//void Print(T1&& arg1, T2&& arg2, T3&& arg3)
//{
//	//...
//}


////包扩展(解析出参数包的内容)
//void ShowList()
//{   //终止条件,参数包是0个时,直接匹配这个函数
//	cout << endl;
//}
//
//
////编译时递归推导解析参数
//template<class T, class ...Args>
//void ShowList(T x, Args... args)
//{
//	//args是N个参数的参数包
//	//调用ShowList,参数包的第一个传给x,剩下N-1传给第二个参数包
//	cout << x << " ";
//	ShowList(args...);
//}
//
//template<class ...Args>
//void Print(Args... args)
//{
//	ShowList(args...);
//}
//
//int main()
//{
//	Print(1, string("xxxxx"), 2.2);
//
//	return 0;
//}
//
//
//
//void ShowList(double x)
//{
//	cout << x << " ";
//	ShowList();
//}
//
//void ShowList(string x, double z)
//{
//	cout << x << " ";
//	ShowList(z);
//}
//
//void ShowList(int x, string y, double z)
//{
//	cout << x << " ";
//	ShowList(y, z);
//}
//
//void Print(int x, string y, double z)
//{
//	ShowList(x, y, z);
//}



//template<class T>
//int GetArg(const T& x)
//{
//	cout << x << " ";
//	return 0;
//}
//
//template<class ...Args>
//void Arguments(Args... args)
//{}
//
//template<class ...Args>
//void Print(Args... args)
//{
//	Arguments(GetArg(args)...);
//	cout << endl;
//}
//
//int main()
//{
//	Print();
//	Print(1);
//	Print(1, string("xxxxx"));
//	Print(1, string("xxxxx"), 2.2);
//
//	return 0;
//}


//int main()
//{
//	list<zsy::string> lt;
//	zsy::string s1("11111");
//	zsy::string s2("22222");
//
//	//传左值,和push_back一样,走拷贝构造
//	lt.emplace_back(s1);
//	cout << "---------------------------------" << endl;
//	lt.push_back(s1);
//	cout << "---------------------------------" << endl << endl;
//
//	//传右值,和push_back一样,走移动构造
//	lt.emplace_back(move(s1));
//	cout << "---------------------------------" << endl;
//	lt.push_back(move(s2));
//	cout << "---------------------------------" << endl << endl;
//
//	//直接传参,隐式类型转换
//	lt.emplace_back("33333");//构造
//	cout << "---------------------------------" << endl;
//	lt.push_back("33333");//构造+移动构造(有临时对象)
//	cout << "---------------------------------" << endl << endl;
//
//	list<pair<zsy::string, int>> lt1;
//	//跟push_back一样
//	pair<zsy::string, int> kv("苹果", 1);
//	lt1.emplace_back(kv);
//	cout << "---------------------------------" << endl;
//	lt1.push_back(kv);
//	cout << "---------------------------------" << endl << endl;
//
//
//	//这里达到的效果是push_back做不到的
//	lt1.emplace_back("苹果",1);//构造
//	cout << "---------------------------------" << endl;
//	lt1.push_back({ "苹果", 1 });//构造+移动构造(有临时对象)
//	cout << "---------------------------------" << endl << endl;
//
//
//	return 0;
//}
 
 
 
//#include"List.h"
//int main()
//{
//	zsy::list<pair<zsy::string, int>> lt1;
//	//跟push_back一样,构造pair+拷贝
//
//	return 0;
//}

//int main()
//{
//	auto add1 = [](int x, int y)->int {return x + y; };
//	cout << add1(1, 2) << endl;
//
//	//1、捕捉为空不能省略
//	//2、参数为空可以省略
//	//3、返回值可以省略,可以通过返回对象自动推导
//	//4、函数体不能省略
//	auto func1 = []
//		{
//			cout << "hello world" << endl;
//			return 0;
//		};
//
//	func1();
//
//	return 0;
//}

struct Goods
{
	string _name;
	double _price;
	int _evaluate;
	//...

	Goods(const char* str,double price,int evaluate)
		:_name(str)
		,_price(price)
		,_evaluate(evaluate)
	{}
};

struct Compare
{

};

